package com.sziit.se.highconcurrency.product.application.controller;

import com.sziit.se.highconcurrency.common.annotation.IgnoreCheck;
import com.sziit.se.highconcurrency.common.constant.Constants;
import com.sziit.se.highconcurrency.common.constant.HttpResponseCodeEnums;
import com.sziit.se.highconcurrency.common.constant.SystemConstants;
import com.sziit.se.highconcurrency.common.entity.UserInfoVo;
import com.sziit.se.highconcurrency.common.exception.CustomException;
import com.sziit.se.highconcurrency.common.result.PageResult;
import com.sziit.se.highconcurrency.common.result.Result;
import com.sziit.se.highconcurrency.common.result.ResultUtil;
import com.sziit.se.highconcurrency.common.tool.FormatFile;
import com.sziit.se.highconcurrency.common.tool.LocalUser;
import com.sziit.se.highconcurrency.product.application.entity.Product;
import com.sziit.se.highconcurrency.product.application.service.IProductService;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author dongchunkeng
 * @since 2022-11-08
 */
@RestController
@AllArgsConstructor
@RequestMapping("/product")
public class ProductController {

    private final IProductService productService;

    @GetMapping
    @IgnoreCheck
    public Result getProductInfo() throws InterruptedException {
        return ResultUtil.data(productService.getAllData());
    }

    /**
     * 只允许admin用户
     * @param productName
     * @param inventory
     * @param price
     * @param image
     * @return
     * @throws IOException
     */

    @PostMapping
    @IgnoreCheck
    public Result addProductInfo(
            @RequestParam("productName")@NotBlank(message = "productName为空")String productName,
            @RequestParam("inventory")@NotBlank(message = "inventory为空")int inventory,
            @RequestParam("price")@NotBlank(message = "price为空")float price,
            @RequestParam("image")MultipartFile image
    ) throws IOException {
        UserInfoVo userInfoVo = LocalUser.getUserNotNull();
        if(!SystemConstants.ADMIN_ROLE.equals(userInfoVo.getRole())) {
            log.println("非管理员，不允许操作");
            throw new CustomException(HttpResponseCodeEnums.FORBIDDEN.getCode(),"非管理员用户，不允许操作");
        }

        //将文件格式统一转成PNG格式
        byte[] imageBytes = null;
        if (null != image) {
            //校验文件后缀
            String fileName = image.getOriginalFilename();
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
            if(!("jpg".equals(suffix) || "JPG".equals(suffix) ||
                    "png".equals(suffix) || "PNG".equals(suffix) ||
                    "svg".equals(suffix) || "SVG".equals(suffix) ||
                    "webp".equals(suffix) || "WEBP".equals(suffix) ||
                    "jpeg".equals(suffix) || "JPEG".equals(suffix) ||
                    "gif".equals(suffix) || "GIF".equals(suffix))) {
                //格式不对，抛出异常
                throw new CustomException(HttpResponseCodeEnums.BAD_REQUEST.getCode(), "图片格式不对");
            }
            imageBytes  = image.getBytes();
            if (!("png".equals(suffix) || "PNG".equals(suffix))){
                imageBytes = FormatFile.convertToPng(imageBytes);
            }

        }
        String productId = UUID.randomUUID().toString();
        return ResultUtil.auto(productService.insertProduct(productId,productName, inventory, price, imageBytes));
    }

    @GetMapping
    @IgnoreCheck
    @RequestMapping("/query-by-id")
    public Result getProductById(@RequestParam(value = "productId") String productId) throws InterruptedException {
        return ResultUtil.data(productService.getOneData(productId));
    }

    /**
     * 只允许ADMIN用户修改
     * @param productId
     * @param productName
     * @param inventory
     * @param price
     * @param image
     * @return
     * @throws Exception
     */
    @PutMapping
    @IgnoreCheck
    @RequestMapping("/update-by-id")
    public Result updateProductById(@RequestParam("productId") @NotBlank(message = "productId为空") String productId,
                                    @RequestParam("productName") String productName,
                                    @RequestParam("inventory") Integer inventory,
                                    @RequestParam("price") Float price,
                                    @RequestParam(value = "image", required = false) MultipartFile image) throws Exception {
        UserInfoVo userInfoVo = LocalUser.getUserNotNull();
        if(!SystemConstants.ADMIN_ROLE.equals(userInfoVo.getRole())) {
            log.println("非管理员，不允许操作");
            throw new CustomException(HttpResponseCodeEnums.FORBIDDEN.getCode(),"非管理员用户，不允许操作");
        }
        byte[] imageBytes = null;
        if (null != image) {
            imageBytes  = image.getBytes();
        }
        Product product = new Product();
        product.setProductId(productId);
        product.setImage(imageBytes);
        product.setProductName(productName);
        product.setPrice(price);
        product.setInventory(inventory);
        Boolean success = productService.updateOneDate(product);
        if (false == success) {
            log.println("update product failed, the productId is " + product.getProductId());
            throw new Exception("update product failed, the productId is " + product.getProductId());
        }
        return ResultUtil.data(productService.getOneData(product.getProductId()));



    }

    /**
     * 内部接口，目前只供订购时修改库存用，不对外开放
     * @param inventory
     * @return
     */
    @PutMapping
    @IgnoreCheck
    @RequestMapping("/inner/update-inventory")
    public Result updateProductInventory(@RequestParam("productId") String productId, @RequestParam("inventory") Integer inventory) throws Exception {
        Product product = new Product();
        product.setProductId(productId);
        product.setInventory(inventory);
        Boolean success = productService.updateOneDate(product);
        if (false == success) {
            log.println("update product failed, the productId is " + product.getProductId());
            throw new Exception("update product failed, the productId is " + product.getProductId());
        }
        return ResultUtil.data(productService.getOneData(product.getProductId()));
    }

    @GetMapping
    @IgnoreCheck
    @RequestMapping("/query-by-page")
    public Result getProductByPage(@RequestParam("pageNumber") @NotBlank(message = "分页查询当前页不能为空") Integer pageNumber,
                                   @RequestParam("pageSize") @NotBlank(message = "分页查询每页记录数不能为空") Integer pageSize,
                                   @RequestParam("productName") String productName,
                                   @RequestParam("price") Float price) throws InterruptedException {
        log.println("enter /query-by-page");
        PageResult<List<Product>> productPage = new PageResult<>();
        pageNumber = pageNumber -1 ;
        productPage.setPageNumber(pageNumber);
        productPage.setPageSize(pageSize);
        int index = pageNumber * pageSize;
        int totalRecord = productService.selectCount(productName, price);
        productPage.setTotal(totalRecord);
        int totalPage = totalRecord / pageSize;
        if (totalRecord % pageSize != 0) {
            totalPage = totalPage + 1;
        }
        productPage.setPages(totalPage);
        List<Product> productList = productService.queryProductByPage(productName, price, index, pageSize);
        productPage.setData(productList);
        productPage.setCode(Constants.ResponseCode.SUCCESS);
        productPage.setMsg("分页查询成功");
        return productPage;
    }


    @GetMapping
    @IgnoreCheck
    @RequestMapping("/image/{productId}")
    public ResponseEntity<byte[]> getProductImage(@PathVariable("productId") String productId) throws InterruptedException {
        log.println("enter /query-by-page");
        Product product = productService.getOneData(productId);
        byte[] bytes = product.getImage();
        HttpHeaders headers =new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);
        return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    }

    @DeleteMapping
    @IgnoreCheck
    @RequestMapping("/{productId}")
    public Result deleteProduct(@PathVariable("productId") String productId) throws InterruptedException {
        log.println("deleteProduct");
        UserInfoVo userInfoVo = LocalUser.getUserNotNull();
        if(!SystemConstants.ADMIN_ROLE.equals(userInfoVo.getRole())) {
            log.println("非管理员，不允许操作");
            throw new CustomException(HttpResponseCodeEnums.FORBIDDEN.getCode(),"非管理员用户，不允许操作");
        }
        return ResultUtil.auto(productService.removeById(productId));
    }
}
